import { RedisService } from '@common/reids/redis.service';
import { RoomService } from '../room/room.service';
import * as axios from 'axios';
import { defaultConfig } from '@game/config/config';
import { Inject, Injectable, forwardRef } from '@nestjs/common';
import { wsGlobal } from '@game/config/config';
import { MyWebSocketGateway } from '../web-socket.gateway';
import { checkHu } from './checkHu';
import { resp } from '../socket/message.utils';

import * as mjAction from './cmmjAction';
import { async } from 'rxjs';
export const adminTest =
  // ["1万", "3万", "5万", "6万", "7万", "8筒", "8筒", "6筒", "6筒", "4筒", "4筒", "中", "中", "5筒"],
  // ["5万", "6万", "4万", "9筒", "9筒", "8筒", "1条", "6筒", "2条", "3条", "南", "南", "中", "7筒",],//7筒
  // ["1万", "3万", "4万", "5万", "6万", "2筒", "3筒", "4筒", "5筒", "7筒", "南", "中", "中", "南"],//南
  // ["1万", "3万", "4万", "5万", "6万", "2筒", "3筒", "4筒", "5筒", "7筒", "中", "中", "中", "8万"],//8万
  // ["2筒", "4筒", "5筒", "6筒", "7筒", "2万", "4万", "5万", "7万", "8万", "8万", "中", "白", "3万"],//3万

  // ["6筒", "6筒", "1条", "3条", "4条", "5条", "6条", "7条", "9条", "7万", "9万", "中", "白", "中"],//中
  // ["3筒", "4筒", "5筒", "5筒", "6筒", "7筒", "3条", "4条", "8条", "8条", "3万", "5万", "白", "4万"],//4万
  // ["9筒", "9筒", "6条", "7条", "8条", "3万", "3万", "4万", "6万", "7万", "7万", "7万", "白", "3万"],//3万
  // ["1筒", "2筒", "3筒", "4筒", "5筒", "6筒", "2万", "5万", "7万", "8万", "中", "中", "白", "4万"],//4万
  // ["2筒", "3筒", "4筒", "7筒", "8筒", "5条", "6条", "7条", "9条", "9条", "7万", "7万", "白", "中"],//中

  // ["5筒", "1条", "2条", "3条", "6条", "7条", "8条", "6万", "7万", "7万", "8万", "9万", "白", "5万"],//5万

  // ["白", "中", "中", "8条", "7条", "7条", "5条", "4条", "3条", "2条", "5万", "3万", "2万", "1万"],//1万
  // ["中", "1条", "3条", "4条", "5条", "6条", "1万", "1万", "2万", "3万", "4万", "5万", "7万", "白"],//白
  // ["白", "9条", "8条", "8条", "7条", "7条", "4条", "3条", "5筒", "4筒", "3筒", "2筒", "2筒", "4条"],//4条

  // ["7万", "8万", "9万", "9条", "9条", "8条", "8条", "4筒", "3筒", "2筒", "1筒", "白", "白", "中"],//"中"
  // ["9万", "8万", "7万", "6万", "4万", "3万", "2万", "1万", "3条", "1条", "1条", "白", "白", "1条"],//

  // ["7万", "7万", "3万", "3万", "9条", "8条", "7条", "8筒", "7筒", "6筒", "5筒", "4筒", "中"],//"7万"
  // ["8万", "7万", "4万", "4万", "9条", "8条", "7条", "7筒", "5筒", "中"],//"2筒"

  // ["8万", "7万", "6万", "4万",  "7筒", "6筒", "5筒", "3条", "3条", "中"],//"9万"

  // ["中", "中", "9条", "8条", "8条", "7条", "6条", "5条", "4条", "3条", "9筒", "7筒", "2筒"],//"8筒"
  // ["中", "中", "中", "中", "8条", "7万", "6条", "5条", "4万", "3条", "9筒", "7筒", "2筒"],//"8筒"
  // ["9条", "9条", "8条", "8条", "7条", "7条", "6条", "6条", "5筒", "5筒", "4筒", "4筒", "3筒"]//"4条"
  // ["8筒", "6筒", "7筒", "9筒", "9筒", "2条", "3条", "4条", "5条", "2万", "3万"]//"4条"
  // ["8筒", "9筒", "7筒", "9筒", "9筒", "2筒", "3筒", "4筒", "6筒", "6筒","6筒","6筒", "3筒"]//"4条"
  // ["8筒", "5筒", "2筒","中", ]//"4条"
  // ["8筒", ]//"4条"
  // ["8筒", "7筒", "7筒","2筒", "5条", "2万", "3万","9万", "8万", "7万", "6万", "4万", "3万", "2万",]//"4条"
  // ["5筒","5筒", "7筒", "7筒", "8筒","8筒","6筒","6筒","6筒","8条","8条","9条","9条"],// 豪7判断
  ["5筒","5筒", "2筒", "2筒", "8筒","8筒","2万","2万","2万","2万","8条","8条","5条" ]//"将将胡判断"
  // ["2筒","2筒", "2筒", "4筒", "4筒","8筒","8筒",], //碰碰胡判断
  // [
  //   '3筒',
  //   '3筒',
  //   '3筒',
  //   '4筒',
  //   '6筒',
  //   '9筒',
  //   '7筒',
  //   '3条',
  //   '3条',
  //   '3条',
  //   '4条',
  //   '6条',
  //   '9条',
  // ]; //板板胡判断
// ["中", "中", "9条", "8条", "8条", "7条", "6条", "5条", "4条", "3条", "9筒", "7筒","2筒"]
const adminTests = [adminTest];
const adminIndex = [];

@Injectable()
export class CMMJService {
  constructor(
    public readonly roomService: RoomService,
    public readonly redisService: RedisService,
    @Inject(forwardRef(() => MyWebSocketGateway))
    public readonly gateway: MyWebSocketGateway,
  ) {

  }

  async begin(roomInfo) {
    // 初始化游戏配置 记录数据库
    console.log('开始游戏配置');
    const roomNum = roomInfo.users.length;
    let seats = roomInfo.users;
    let game = {
      ...roomInfo,
      isCsJiang: true,
      model: 1,
      roomId: roomInfo.roomId,
      sceneId: roomInfo.sceneId,
      numOfGames: roomInfo.numOfGames,
      maxGames: roomInfo.maxGames,
      //第一把随机庄家
      button:
        roomInfo.numOfGames != 0
          ? (roomInfo.nextButton||0)
          : Math.floor(Math.random() * roomNum),
      mahjongs: [],
      shazi: true,
      random: [],
      currentIndex: 0,
      foldsNum: 0,
      gameSeats: [],
      turn: 0,
      laizi: [31],
      chuPai: -1,
      state: 'playing',
      yipaoduoxiang: -1,
      guoshoupeng: {},
      zhuanyi: -1,
      actionList: [],
      gangkai: [],
      hupaiList: [],
      chupaiCnt: 0, //记录本局出牌数
      lastMopai: 0,
      oldturn: {}, //用户上一轮摸牌
    };

    // 记录房间数据
    for (let i = 0; i < roomNum; ++i) {
      let data: any = (game.gameSeats[i] = {});

      data.seatIndex = i;
      data.userId = roomInfo.users[i].userId;
      data.socket_ip = roomInfo.users[i].socket_ip;
      data.online = roomInfo.users[i].status==2?true:false;
      data.name=roomInfo.users[i].nickName;
      data.score=roomInfo.users[i].score||0;
      data.ready=roomInfo.users[i].ready;
      //持有的牌
      data.holds = [];
      //打出的牌
      data.folds = [];
      //暗杠的牌
      data.penggangs = [];
      //玩家手上的牌的数目，用于快速判定碰杠
      data.countMap = {};
      //玩家听牌，用于快速判定胡了的番数
      data.tingMap = {};
      //是否可以杠
      data.canGang = false;
      data.canGangHu = false;
      //用于记录玩家可以杠的牌
      data.gangPai = [];

      (data.canChi = false),
        (data.chi = []), //记录吃的牌
        (data.chiPai = []), // 可吃的牌
        //是否可以碰
        (data.canPeng = false);
      //是否可以胡
      data.canHu = false;
      //是否可以出牌
      data.canChuPai = false;

      data.guoHuTime = 0;

      //是否胡了
      data.hued = false;
      //是否是自摸
      data.iszimo = false;

      data.isGangHu = false;
      //
      data.actions = [];

      data.fan = 0;
      data.pattern = '';
      data.lastFangGangSeat = -1;

      //统计信息
      data.numZiMo = 0;
      data.numJiePao = 0;
      data.numDianPao = 0;
      data.numAnGang = 0;
      data.numMingGang = 0;
    }
    //洗牌
    //强制清0
    game.currentIndex = 0;
    this.shuffle(game);
    this.deal(game);

    // console.log(game.gameSeats)
    // 计算剩余牌数，定位到当前索引
    let numOfMJ = game.mahjongs.length - game.currentIndex;
    game.foldsNum=numOfMJ;
    let allHolds = [];
    for (let i = 0; i < seats.length; i++) {
      if (!game.gameSeats[i]) continue;

      //开局时，通知前端必要的数据
      let s = seats[i];
      //通知玩家手牌
      let data: any = { userId: s.userId, holds: game.gameSeats[i].holds };
      console.log(checkHu.getName(game.gameSeats[i].holds));
      this.gateway.send({
        ...s,
        roomId: game.roomId,
        type: resp.game_holds,
        message: data,
      });
      allHolds.push(data);
      //通知还剩多少张牌
      this.gateway.send({
        ...s,
        roomId: game.roomId,
        type: resp.mj_count,
        message: numOfMJ,
      });
      //通知还剩多少局
      this.gateway.send({
        ...s,
        roomId: game.roomId,
        type: resp.game_num,
        message: roomInfo.numOfGames,
      });
      //通知游戏开始
      this.gateway.send({
        ...s,
        roomId: game.roomId,
        type: resp.game_begin,
        message: game,
      });
    }


    const len = game.gameSeats.length;
    let random1 = Math.floor(Math.random() * 6);
    let random2 = Math.floor(Math.random() * 6);
    let random = [random1, random2];
   game.random =random
   let isQishou=false
    //进行听牌检查
    for (let m = 0; m < len; ++m) {
      let duoyu = -1;
      let gs = game.gameSeats[m];
      if (gs.holds.length == 14) {
        duoyu = gs.holds.pop();
        gs.countMap[duoyu] -= 1;
      }
      isQishou =await this.qishou(game, gs,random);
    
      await mjAction.checkTingPai(game, gs, this);
      if (duoyu >= 0) {
        gs.holds.push(duoyu);
        gs.countMap[duoyu]++;
      }
    
    }
    
    await this.redisService.hset({
      key: 'game' + game.roomId,
      value: { ...game },
      expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
    });
   
    let turnSeat = game.gameSeats[game.turn];
    game.state = 'playing';
    //通知玩家出牌方
    turnSeat.canChuPai = true;
    // 告诉到哪个出牌
    this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: turnSeat.userId,
      message: turnSeat.userId,
      type: resp.game_chupai,
      includSender: true,
    });
    if(isQishou){
      return game
    }
    this.checkAnGang(game)
    return game;
  }


  async beginBefore(roomInfo){
    console.log('初始化游戏配置');
    const roomNum = roomInfo.users.length;
    let game = {
      ...roomInfo,
      roomId: roomInfo.roomId,
      sceneId: roomInfo.sceneId,
      numOfGames: roomInfo.numOfGames,
      maxGames: roomInfo.maxGames,
      //第一把随机庄家
      button:
        roomInfo.numOfGames != 1
          ? roomInfo.nextButton
          : Math.floor(Math.random() * roomNum),
      mahjongs: [],
      gameSeats: [],
      turn: 0,
      status: 3,//覆盖roomInfo状态
      state: 'idle',
     
    };

    // 记录房间数据
    for (let i = 0; i < roomNum; ++i) {
      let data: any = (game.gameSeats[i] = {});
      data.seatIndex = i;
      data.userId = roomInfo.users[i].userId;
      data.socket_ip = roomInfo.users[i].socket_ip;
      data.online = roomInfo.users[i].status==2?true:false;
      data.name=roomInfo.users[i].nickName;
      data.score=roomInfo.users[i].amount;
      data.ready=roomInfo.users[i].ready;
      //统计信息
      data.penggangs = [];
      data.gangPai = [];
      (data.canChi = false),
      (data.chi = []), //记录吃的牌
      (data.chiPai = []), // 可吃的牌
      data.numZiMo = 0;
      data.numJiePao = 0;
      data.numDianPao = 0;
      data.numAnGang = 0;
      data.numMingGang = 0;
    }
    return game
  }

  async gameOver(roomInfo){
      let endInfo = await this.roomService.getRound(roomInfo.sceneId);
      let data =null;
      if(endInfo && endInfo.scores){
        let  finalRes = JSON.parse(endInfo.scores)
        data = {results:finalRes.users, endInfo: finalRes}
      }
      if(data){
        this.gateway.broadcastInRoom({
          roomId: roomInfo.roomId,
          // userId: userId,
          message: data,
          type: resp.game_over,
          includSender: true,})
      }
    }
  

  async reconnection(game, dataUser) {
    let isQishou=false
    let gs = game.gameSeats.find((item) => item.userId == dataUser.userId);
    let holds =gs.holds.slice(0)
    console.log(
      checkHu.getName(checkHu.sort(holds)).toString(),
    );
    isQishou =gs.folds.length>0?false:true
    //通知玩家手牌
    let numOfMJ = game.mahjongs.length - game.currentIndex;

    let data: any = { userId: gs.userId, holds:gs.holds };

    this.gateway.send({
      ...gs,
      roomId: game.roomId,
      type: resp.game_holds,
      message: data,
    });
    //通知还剩多少张牌
    this.gateway.send({
      ...gs,
      roomId: game.roomId,
      type: resp.mj_count,
      message: numOfMJ,
    });
    //通知还剩多少局
    this.gateway.send({
      ...gs,
      roomId: game.roomId,
      type: resp.game_num,
      message: game.numOfGames,
    });
    //通知游戏开始
    this.gateway.send({
      ...gs,
      roomId: game.roomId,
      type: resp.game_begin,
      message: game,
    });

    if( game.state == 'idle'){

      this.doGameOver(game,gs.userId,false,true)
      return 
    }

    //不允许出现小相公
    let turnSeat = game.gameSeats[game.turn];
   
    let l = turnSeat.holds.length;
    if (l == 2 || l == 5 || l == 8 || l == 11 || l == 14) {
          let turnSeat = game.gameSeats[game.turn];
          //通知玩家出牌方
          turnSeat.canChuPai = true;
          // 告诉到哪个出牌
          this.gateway.broadcastInRoom({
            seats: game.gameSeats,
            roomId: game.roomId,
            userId: turnSeat.userId,
            message: turnSeat.userId,
            type: resp.game_chupai,
            includSender: true,
          });

    }
    else{
      game.chuPai = -1;
      this.moveToNextUser(game)
      this.doUserMoPai(game,null)
    }

    if( game.foldsNum ==numOfMJ){
         //进行听牌检查
          for (let m = 0; m < game.gameSeats.length; m++) {
            let duoyu = -1;
            let gs = game.gameSeats[m];
            if (gs.holds.length == 14) {
              duoyu = gs.holds.pop();
              gs.countMap[duoyu] -= 1;
            }
            isQishou =await this.qishou(game, gs,game.random);
          
            await mjAction.checkTingPai(game, gs, this);
            if (duoyu >= 0) {
              gs.holds.push(duoyu);
              gs.countMap[duoyu]++;
            }
          
          }
          await this.redisService.hset({
            key: 'game' + game.roomId,
            value: { ...game },
            expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
          });


          if(isQishou){
            return game
          }
    }

    this.checkAnGang(game)
  
    
    
    console.log('重连广播一次');
  }

  async qishou_notify(game,userId,isQishou,message){
    let seatData = game.gameSeats.find((item) => item.userId == userId);
    if(isQishou){

      seatData.isQishou=false
      await this.redisService.hset({
        key: 'game' + game.roomId,
        value: { ...game },
        expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
      });
      for (let index = 0; index <  game.gameSeats.length; index++) {
        const element =  game.gameSeats[index];
        if (element.isQishou) {
          console.log('wait qishou.');
          return false;
        }
      }
      let msg = {
        ...seatData,
        roomId: game.roomId,
        type: resp.qishou_notify,
        message:message,
        includSender: true,

      };
    await  this.gateway.broadcastInRoom(msg);

     

    }else{
      for (let index = 0; index < seatData.actions.length; index++) {
        const ac =  seatData.actions[index];
        if (
          ac.type == 'BanBanHu' ||
          ac.type == 'QueYiSe' ||
          ac.type == 'YiZhiHua' ||
          ac.type == 'DaSiXi' ||
          ac.type == '66Shun'
        ) {
          ac.targets=[]
        } 
      }
      seatData.isQishou=false
      await this.redisService.hset({
        key: 'game' + game.roomId,
        value: { ...game },
        expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
      });
    }

    this.checkAnGang(game)

  
  }

 async checkAnGang(game){
    for (let index = 0; index <  game.gameSeats.length; index++) {
      const gs = game.gameSeats[index];
  
       // //检查当前是否可以暗杠或者胡
       if (game.turn == gs.seatIndex) {
        await  this.checkMoPai(game, gs, gs.holds[gs.holds.length - 1]);
           // 推送暗杆的前提是 gangting
           if(gs.canGang){
            //去掉杠牌能不能胡
           let pais =gs.holds.slice(0)
            for (let m = 0; m < gs.gangPai.length; m++) {
              let pai =gs.gangPai[m];
              if (gs.holds) {
                for (let i = 0; i <= 4; ++i) {
                  let idx = gs.holds.indexOf(pai);
                  if (idx == -1) {
                    //如果没有找到，表示移完了，直接跳出循环
                    break;
                  }
                  gs.holds.splice(idx, 1);
                }
              }
              await mjAction.checkTingPai(game, gs, this);
              if(gs.tingMap.length>0){
                // 说明能开杠了
              await  this.gateway.send({
                  ...gs,
                  roomId: game.roomId,
                  message: { userId: gs.userId, gangpai: gs.gangPai, angang: true},
                  type: resp.angang_notify,
                });
              }
            }
            gs.holds=pais;
          }
        }
      
     }
  }
  async qishou(game: any, seatData: any,random) {
    let isQishou=false
    let round = null;
    // 过滤条件 "{"banbanhu":0,"queyise":1,"danwu":1,"dasixi":1,"liuliushun":1}"
    let qiShouHu_BBH=JSON.parse(game.qiShouHu)
    round = [
      (seatData.seatIndex + random[0] + 3) % 4,
      (seatData.seatIndex + random[1] + 3) % 4,
    ];
    let holds =seatData.holds.slice(0)
    let msg = {
      ...seatData,
      roomId: game.roomId,
      type: resp.qishou,
      message: { pattern: '', shazi: game.shazi ? random : null ,userId:seatData.userId},
    };
    // 板板胡 不需要将
    let isBanBanHu = checkHu.checkBanBanHu(holds, game.laizi);
    if (isBanBanHu && qiShouHu_BBH.banbanhu==1) {
      mjAction.recordUserAction(game, seatData, 'BanBanHu', round);
      msg.message = { ...msg.message, pattern: msg.message.pattern+',BanBanHu' };
      console.log('板板胡 不需要将 且13、14张:', isBanBanHu);
    }
    let isQueYiSe = checkHu.checkQueYiSe(holds, game.laizi);
    if (isQueYiSe  && qiShouHu_BBH.queyise==1) {
      mjAction.recordUserAction(game, seatData, 'QueYiSe', round);
      msg.message = { ...msg.message, pattern: msg.message.pattern+',QueYiSe' };
      console.log('缺一色:', isQueYiSe);
    }
    let isYiZhiHua = checkHu.checkYiZhiHua(holds, game.laizi);
    if (isYiZhiHua   && qiShouHu_BBH.danwu==1 ) {
      mjAction.recordUserAction(game, seatData, 'YiZhiHua', round);
      msg.message = { ...msg.message, pattern: msg.message.pattern+',YiZhiHua' };
      console.log('单五一枝花:', isYiZhiHua);
    }
    let isDaSiXi = checkHu.checkDaSiXi(holds, game.laizi);
    if (isDaSiXi  && qiShouHu_BBH.dasixi==1 ) {
      mjAction.recordUserAction(game, seatData, 'DaSiXi', round);
      msg.message = { ...msg.message, pattern: msg.message.pattern+',DaSiXi' };
      console.log('四喜:', isDaSiXi);
    }
    let is66Shun = checkHu.check66Shun(holds, game.laizi);
    if (is66Shun  && qiShouHu_BBH.liuliushun==1 ) {
      mjAction.recordUserAction(game, seatData, '66Shun', round);
      msg.message = { ...msg.message, pattern: msg.message.pattern+',66Shun' };
      console.log('66顺:', is66Shun);
    }

    if( msg.message.pattern.length>0){
      msg.message.pattern = msg.message.pattern.substring(1,msg.message.pattern.length);
      seatData.isQishou=true
      isQishou=true
      this.gateway.send(msg);

    }
    return isQishou
  }

  shuffle(game) {
    let mahjongs = game.mahjongs;
    //初始化牌组
    for (let i = 0; i < 27; i++) {
      mahjongs.push(i, i, i, i);
    }
    //红中
    // mahjongs.push(31, 31, 31, 31);
    console.log("麻将总数:",mahjongs.length)
    //数组重新排序
    for (let i = 0; i < mahjongs.length; ++i) {
      let lastIndex = mahjongs.length - 1 - i;
      let index = Math.floor(Math.random() * lastIndex);
      let t = mahjongs[index];
      mahjongs[index] = mahjongs[lastIndex];
      mahjongs[lastIndex] = t;
    }

    adminIndex.map((index, i) => {
      console.log('dyh', i + '');
      let cardList: any = checkHu.sort(checkHu.getPointList(adminTests[i]));
      console.log('cardList: ', cardList);
      game.gameSeats[index].holds = cardList.slice(0);
      //测试听牌
      for (let i = 0; i < mahjongs.length;i++) {
        if (cardList.includes(mahjongs[i])) {
          for (let j = 0; j < cardList.length;j++) {
            if (cardList[j] == mahjongs[i]) {
              cardList.splice(j, 1);
              mahjongs.splice(i, 1);
              j--;
              i--;
              break;
            }
          }
        }
      }
      console.log("新麻将总数:",mahjongs.length)

      //统计牌的数目 ，用于快速判定（空间换时间）
      game.gameSeats[index].holds.map((pai) => {
        let c = game.gameSeats[1].countMap[pai];
        if (c == null) {
          c = 0;
        }
        game.gameSeats[index].countMap[pai] = c + 1;
      });
    });
    console.log('洗牌结束');
  }

  deal(game) {
    const roomNum = game.gameSeats.length;
    //每人13张 一共 13*4 ＝ 52张 庄家多一张 53张
    // 庄家先发牌逻辑  这里要排除测试座位的摸牌
    let seatIndex = 0; //庄家先发牌逻辑
    for (let i = 0; i < 13 * roomNum; i++) {
      // 这里要排除测试座位的摸牌
      if (!adminIndex.includes(seatIndex)) {
        this.mopai(game, seatIndex);
      }
      seatIndex++; // 0 1 2 3
      seatIndex %= roomNum; // 0 1 0 1
    }

    // //庄家多摸最后一张
    this.mopai(game, game.button,false,0);
    //当前轮设置为庄家
    game.turn = game.button;
    console.log('发牌结束', game.turn);
    console.log("当前索引:",game.currentIndex)
  }

  mopai(game, seatIndex, isGang = false,isTest=0) {
    if (game.currentIndex == game.mahjongs.length) {
      return -1;
    }
    console.log('发牌', seatIndex, game.gameSeats[seatIndex].userId);

    let data = game.gameSeats[seatIndex];
    let mahjongs = data.holds;
    let pai = game.mahjongs[game.currentIndex];
    if (isGang) {
      let temp = pai;
      pai = game.mahjongs[game.mahjongs.length - 1 - game.lastMopai];
      game.mahjongs[game.currentIndex] = pai;
      game.mahjongs[game.mahjongs.length - 1 - game.lastMopai] = temp;
      game.lastMopai++;
    }

    game.currentIndex++;
    mahjongs.push(isTest>0?isTest:pai);
    //统计牌的数目 ，用于快速判定（空间换时间）
    let c = data.countMap[pai];
    if (c == null) {
      c = 0;
    }
    data.countMap[pai] = c + 1;
    return pai;
  }

  async gangmopai(game, seatIndex, isGang = false) {
    if (game.currentIndex == game.mahjongs.length) {
      return -1;
    }
    let data = game.gameSeats[seatIndex];

    let mahjongs = data.holds;
    let numOfMJ = game.mahjongs.length - game.currentIndex;
    let leng = 4 - numOfMJ > 0 ? numOfMJ : 4;
    let pais = [];
    for (let index = 0; index < leng; index++) {
      let pai = game.mahjongs[game.currentIndex];
      if (isGang) {
        let temp = pai;
        pai = game.mahjongs[game.mahjongs.length - 1 - game.lastMopai];
        game.mahjongs[game.currentIndex] = pai;
        game.mahjongs[game.mahjongs.length - 1 - game.lastMopai] = temp;
        game.lastMopai++;
      }
      game.currentIndex++;
      pais.push(pai);
    }
    game.gangkai=pais
    game.gangpao=pais
    if (leng == 0) {
      this.doGameOver(game, data.userId);
      return false;
    }
    let numOfMJ2 = game.mahjongs.length - game.currentIndex;

    this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: data.userId,
      message: { pais: pais},
      type: resp.gangpai,
      includSender: true,
    });
    let isHued=false
    let type='ganghua'
    let notify=-1
    for(let pai of pais){
       //优先自己
       for (let i = 0; i < data.tingMap.length; i++) {
        if (data.tingMap[i][1].includes(pai)) {
          data.canHu = true;
          // 记录一下下
          // mjAction.recordUserAction(game, data, data.tingMap[i][0]);
          console.log("累计胡:",pai)
          await mjAction.hu(game, data.userId,pai, this,(game,userId,type2,notify2)=>{
            isHued=true
            type=type2
            notify=notify2
          });
        }
      }
    }
    // await mjAction.clearAllOptions(game,data)
    if(isHued){
      await this.gateway.broadcastInRoom({
        seats: game.gameSeats,
        roomId: game.roomId,
        userId:  data.userId,
        message: { userId:  data.userId,iszimo:true, type: type, hupai: notify,zhongma:game.zhongma },
        type: resp.game_hupai,
        includSender: true,
      });
      this.doGameOver(game,  data.userId)
      return false;
    }

    this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: data.userId,
      message: numOfMJ2,
      type: resp.mj_count,
      includSender: true,
    });
    //移除过手碰
    if (game.guoshoupeng[data.userId] != null) {
      delete game.guoshoupeng[data.userId];
    }
    //广播通知玩家出牌方
    if (!data.canHu) {
      game.yipaoduoxiang = -1;
      for (let i = 0; i < game.gameSeats.length; ++i) {
        let ddd = game.gameSeats[i];
        if (ddd.seatIndex == data.seatIndex) {
          continue;
        }
        //已经和牌的不再检查
        if (ddd.hued) {
          continue;
        }
        let hupai = [];
        for (let i = 0; i < ddd.tingMap.length; i++) {
          let pai =ddd.tingMap[i][1].find(item=>pais.find(item2=>item2==item))
          if (pai) {
            ddd.canGangHu = true
            hupai.push(pai)
          }
        }
        if(hupai.length>0){
          await this.sendOperations(game, ddd, hupai);
        }
      }
    } else {
      console.log('gang hua over');
    }
  }

  async loopgang(game, pai) {
    //检查是否有人要胡，要碰 要杠
    let hasActions = false;
    for (let i = 0; i < game.gameSeats.length; ++i) {
      let ddd = game.gameSeats[i];
      //已经和牌的不再检查
      if (ddd.hued) {
        continue;
      }
      //有人开杠 彭就没了
      let kaigang = this.checkCanDianGang(game, ddd, pai);
      let kaipeng = this.checkCanPeng(ddd, pai);
      if (this.hasOperations(ddd)) {
        await this.sendOperations(game, ddd,pai);
        hasActions = true;
      }
    }
    // peng、gang都可能存在的情况下，能不能吃
    if (this.checkChi(game, pai)) {
      hasActions = true;
    }
    //如果没有人有操作，则向下一家发牌，并通知他出牌
    if (!hasActions) {
      game.chuPai = -1;
      await this.moveToNextUser(game);
      await this.doUserMoPai(game, null);
    }
  }

 async checkMoPai(game, turnSeat, pai) {
    //检查是否可以暗杠或者胡
    //检查胡，直杠，弯杠
  await  this.checkCanAnGang(game, turnSeat);
    //检查看是否可以和
  await  this.checkCanHu(game, turnSeat, pai);
    //通知当前玩家做对应操作
   await this.sendOperations(game, turnSeat, game.chuPai);
  }

  //检查是否可以暗杠
  async checkCanAnGang(game, seatData) {
    //如果没有牌了，则不能再杠
    if (game.currentIndex >= game.mahjongs.length) {
      return false;
    }

    for (const key in seatData.countMap) {
      if (Object.prototype.hasOwnProperty.call(seatData.countMap, key)) {
        const pai =Number(key);
        let c = seatData.countMap[key];
      if (c == 4) {
        seatData.canGang = true;
        if(!seatData.gangPai.includes(pai)){
          seatData.gangPai.push(pai);
        }
      }
      }
    }
  }

  async checkCanHu(game, seatData, targetPai) {
    //game.lastHuPaiSeat = -1;
    seatData.canHu = false;

    let count = 0;
    for (let i = 0; i < game.laizi.length; i++) {
      //鬼牌大于等于4，直接胡牌
      count += seatData.countMap[game.laizi[i]];
    }
    if (count > 3) {
      seatData.canHu = true;
    }
    // 累计计算
    for (let i = 0; i < seatData.tingMap.length; i++) {
      if (seatData.tingMap[i][1].includes(targetPai)) {
        seatData.canHu = true;
        break;
      }
    }
  }

  checkChi(game, targetPai) {
    if(targetPai==-1){
      return false
    }
    // 下个轮次才有资格 且插入holds进行排序 连续三个一句话
    let i = game.turn;
    i++;
    i %= game.gameSeats.length;
    let turnSeat = game.gameSeats[i];
    //拿到holds
    let cardList: any = checkHu.chiPai(turnSeat.holds, targetPai);
    if (cardList.length > 0) {
      turnSeat.canChi = true;
      turnSeat.chiPai = cardList;
      turnSeat.pai = targetPai;
      let data: any = { pais: cardList,pai:targetPai};
      data.chi = true;
      this.gateway.send({
        ...turnSeat,
        roomId: game.roomId,
        type: resp.game_action,
        message: data,
      });

      return true;
    }
    return false;
  }

  hasOperations(seatData) {
    if (seatData.canGang || seatData.canPeng || seatData.canHu || seatData.canGangHu) {
      return true;
    }
    return false;
  }

  async sendOperations(game, seatData, pai) {
    if (this.hasOperations(seatData)) {
      //保存游戏  socket消息过快 缓存数据没更新到 导致有动作但是状态不对
      await this.redisService.hset({
        key: 'game' + game.roomId,
        value: { ...game },
        expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
      });
      if (pai == -1) {
        //起手
        pai = seatData.holds[seatData.holds.length - 1];
      }

    
      if (seatData.canHu) {
        let data: any = { pai: pai };
        data.hu = true;
        //如果可以有操作，则进行操作
        await this.gateway.send({
          ...seatData,
          roomId: game.roomId,
          message: data,
          type: resp.game_action,
        });
      }
      if (seatData.canGangHu) {
        let data: any = { pais: pai };
        data.canGangHu = true;
        //如果可以有操作，则进行操作
        await this.gateway.send({
          ...seatData,
          roomId: game.roomId,
          message: data,
          type: resp.game_action,
        });
      }
      if (seatData.canGang) {
        let data: any = { pai: pai };
        data.gang = true;
        data.gangpai = seatData.gangPai;
        //如果可以有操作，则进行操作
        await this.gateway.send({
          ...seatData,
          roomId: game.roomId,
          message: data,
          type: resp.game_action,
        });
      }
      if (seatData.canPeng) {
        let data: any = { pai: pai };
        data.peng = true;
        await this.gateway.send({
          ...seatData,
          roomId: game.roomId,
          message: data,
          type: resp.game_action,
        });
      }
    } 
  }

  /////////////////////////////////////
  /**
   * 规则流转 需要该场景数据了
   */
  async chuPai(game, userId, paiStr) {
    let pai = Number(paiStr);
    game.yipaoduoxiang = -1;
    let seatData = game.gameSeats.find((item) => item.userId == userId);

    if (seatData == null) {
      console.log("can't find user game data.");
      return false;
    }

    let seatIndex = seatData.seatIndex;
    //如果不该他出，则忽略
    if (game.turn != seatData.seatIndex) {
      console.log('not your turn.', game.turn);
      return false;
    }

    if (seatData.hued) {
      console.log('you have already hued. no kidding plz.');
      return false;
    }

    for (let index = 0; index <  game.gameSeats.length; index++) {
      const element =  game.gameSeats[index];
      if (element.isQishou) {
        console.log('no need chupai.');
        return false;
      }
    }
   
    

    // if (seatData.canChuPai == false) {
    //   console.log('no need chupai.');
    //   return false;
    // }

    if (this.hasOperations(seatData)) {
      console.log('plz guo before you chupai.', seatData.canGang , seatData.canPeng , seatData.canHu);
      return false;
    }

    //从此人牌中扣除
    let index = seatData.holds.indexOf(pai);
    if (index == -1) {
      console.log('holds:' + seatData.holds);
      console.log("can't find mj." + pai);
      let data: any = { userId: seatData.userId, holds:seatData.holds };

      this.gateway.send({
        ...seatData,
        roomId: game.roomId,
        type: resp.game_holds,
        message: data,
      });
      return false;
    }

    seatData.canChuPai = false;
    game.chupaiCnt++;
    seatData.guoHuFan = -1;

    seatData.holds.splice(index, 1);
    seatData.countMap[pai]--;
    game.chuPai = pai;

    await mjAction.checkTingPai(game, seatData, this);
// 如果听牌 要推送给前端

   await this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: seatData.userId,
      message: { userId: seatData.userId, pai: pai },
      type: resp.game_chupai_notify,
      includSender: true,
    });
    //如果出的牌可以胡，则算过胡
    // if (seatData.tingMap[game.chuPai]) {
    //   seatData.guoHuTime++;
    // }
    for (let i = 0; i < seatData.tingMap.length; i++) {
      if (seatData.tingMap[i][1].includes(game.chuPai)) {
        seatData.guoHuTime++;
        break;
      }
    }
    //检查是否有人要胡，要碰 要杠
    let hasActions = false;
    for (let i = 0; i < game.gameSeats.length; ++i) {
      //玩家自己不检查
      if (game.turn == i) {
        continue;
      }
      let ddd = game.gameSeats[i];
      //已经和牌的不再检查
      if (ddd.hued) {
        continue;
      }
    
      if (
        game.guoshoupeng[ddd.userId] == null ||
        game.guoshoupeng[ddd.userId][pai] == null
      ) {
        //当前用户未被限制，才能碰
        this.checkCanPeng(ddd, pai);
      }
      //先检查杠
      this.checkCanDianGang(game, ddd, pai);
      let isFangPao=game.isFangPao ||1

      if(isFangPao ==1){
        this.checkCanHu(game, ddd, pai);
      }

      if (this.hasOperations(ddd)) {
        await this.sendOperations(game, ddd, game.chuPai);
        hasActions = true;
      }
    }

    // peng、gang都可能存在的情况下，能不能吃
    if (this.checkChi(game, pai)) {
      hasActions = true;
    }

    //如果没有人有操作，则向下一家发牌，并通知他出牌
    if (!hasActions) {
      // this.gateway.broadcastInRoom({
      //   seats: game.gameSeats,
      //   roomId:game.roomId,
      //   userId: seatData.userId,
      //   message: { userId: seatData.userId, pai: game.chuPai },
      //   type: resp.guo_notify,
      //   includSender: true,
      // });
      
      // 不碰吃杠的情况下 这样处理  有action动作自己的folds就没有了
      seatData.folds.push(game.chuPai);
      game.chuPai = -1;
      await this.moveToNextUser(game);
      await this.doUserMoPai(game, null);
    }
  }

  async moveToNextUser(game, nextSeat = null) {
    game.fangpaoshumu = 0;
    //找到下一个没有和牌的玩家
    if (nextSeat == null) {
      while (true) {
        game.turn++;
        game.turn %= game.gameSeats.length;
        let turnSeat = game.gameSeats[game.turn];
        if (turnSeat.hued == false) {
          break;
        }
      }
    } else {
      game.turn = nextSeat;
    }
    //保存游戏  socket消息过快 缓存数据没更新到 导致有动作但是状态不对
    await this.redisService.hset({
      key: 'game' + game.roomId,
      value: { ...game },
      expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
    });
    console.log('game turn:', game.turn);
  }

  async doUserMoPai(game, isGang) {
    game.chuPai = -1;
    let turnSeat = game.gameSeats[game.turn];
    if(!isGang){
     turnSeat.lastFangGangSeat = -1;
    }

    // 补张就屁胡  杠就是听牌下 抓四张 且锁定 牌型
    if (isGang && !turnSeat.buzhang && turnSeat.tingMap.length > 0) {
      this.gangmopai(game, game.turn, isGang ? true : false);
      return false;
    }
    let pai = this.mopai(game, game.turn, isGang ? true : false);
    //牌摸完了，结束
    if (pai == -1) {
      this.doGameOver(game, turnSeat.userId);
      return false;
    } else {
      let numOfMJ = game.mahjongs.length - game.currentIndex;

      await  this.gateway.broadcastInRoom({
        seats: game.gameSeats,
        roomId: game.roomId,
        userId: turnSeat.userId,
        message: numOfMJ,
        type: resp.mj_count,
        includSender: true,
      });
    }
    //移除过手碰
    if (game.guoshoupeng[turnSeat.userId] != null) {
      delete game.guoshoupeng[turnSeat.userId];
    }

    //广播通知玩家出牌方
    turnSeat.canChuPai = true;

    console.log('摸到新牌');
    console.log(turnSeat.userId + '摸到新牌：', pai, checkHu.getName([pai]));

    
    //通知前端新摸的牌
    await this.gateway.send({
      ...turnSeat,
      roomId: game.roomId,
      type: resp.game_mopai,
      message: { userId:turnSeat.userId,pai },
    });
    // await this.gateway.broadcastInRoom({
    //   seats: game.gameSeats,
    //   roomId: game.roomId,
    //   userId: turnSeat.userId,
    //   message: {  userId:turnSeat.userId,pai },
    //   type: resp.game_mopai,
    //   includSender: false,
    // });
    await this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: turnSeat.userId,
      message: turnSeat.userId,
      type: resp.game_chupai,
      includSender: true,
    });
    this.checkCanWanGang(game, turnSeat);
   await this.checkMoPai(game, turnSeat, pai);

     // 推送暗杆的前提是 gangting
     if(turnSeat.canGang){
      //去掉杠牌能不能胡
     let pais =turnSeat.holds.slice(0)
      for (let m = 0; m < turnSeat.gangPai.length; m++) {
        let pai =turnSeat.gangPai[m];
        if (turnSeat.holds) {
          for (let i = 0; i <= 4; ++i) {
            let idx = turnSeat.holds.indexOf(pai);
            if (idx == -1) {
              //如果没有找到，表示移完了，直接跳出循环
              break;
            }
            turnSeat.holds.splice(idx, 1);
          }
        }
        await mjAction.checkTingPai(game, turnSeat, this);
        if(turnSeat.tingMap.length>0){
          // 说明能开杠了
          this.gateway.send({
            ...turnSeat,
            roomId: game.roomId,
            message: { userId: turnSeat.userId, gangpai: turnSeat.gangPai, angang: true},
            type: resp.angang_notify,
          });
        }
      }
      turnSeat.holds=pais;
    }
     //保存游戏  socket消息过快 缓存数据没更新到 导致有动作但是状态不对
     await this.redisService.hset({
      key: 'game' + game.roomId,
      value: { ...game },
      expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
    });
  }

  //检查是否可以弯杠(自己摸起来的时候)
  checkCanWanGang(game, seatData) {
    //如果没有牌了，则不能再杠
    if (game.currentIndex >= game.mahjongs.length) {
      return false;
    }
    //从碰过的牌中选
    for (let i = 0; i < seatData.penggangs.length; ++i) {
      if (seatData.penggangs[i][0] != 'peng') continue;
      let pai = seatData.penggangs[i][1];
      if (seatData.countMap[pai] == 1) {
        seatData.canGang = true;
        seatData.gangPai.push(pai);
      }
    }
  }

  //检查是否可以碰
  checkCanPeng(seatData, targetPai) {
    let count = seatData.countMap[targetPai];
    if (count != null && count >= 2) {
      seatData.canPeng = true;
      return true;
    }

    return false;
  }

  //检查是否可以点杠
  checkCanDianGang(game, seatData, targetPai) {
    //检查玩家手上的牌
    //如果没有牌了，则不能再杠
    if (game.currentIndex >= game.mahjongs.length) {
      return false;
    }
    let count = seatData.countMap[targetPai];
    if (count != null && count >= 3) {
      seatData.canGang = true;
      seatData.gangPai.push(targetPai);
      return true;
    }
    return false;
  }
  async peng(game, userId) {
    return await mjAction.peng(game, userId, this,async (game, nextSeat) => {
      await this.moveToNextUser(game, nextSeat);
    });
  }
  async dochi(game, userId, index) {
  return  await mjAction.dochi(
      game,
      userId,
      index,
      this,
      async (game, nextSeat) => {
        await this.moveToNextUser(game, nextSeat);
      },
    );
  }
  async gang(game, userId, pai, buzhang) {
    return  await mjAction.gang(
      game,
      userId,
      Number(pai),
      buzhang,
      this,
      async  (game, nextSeat) => {
        await this.moveToNextUser(game, nextSeat);
      },
      async (game, isGang) => {
        await  this.doUserMoPai(game, isGang);
      },
    );
  }
  async hu(game, userId,pai) {
    let isHued=false
    let type=""
    let notify=-1
    let iszimo=false
    for (let index = 0; index < game.gameSeats.length; index++) {
      const element = game.gameSeats[index];
     if(element.canGangHu){
        for(let pai of game.gangpao){
          for (let i = 0; i < element.tingMap.length; i++) {
            if (element.tingMap[i][1].includes(pai)) {
              element.canHu = true;
              // 记录一下下
              // mjAction.recordUserAction(game, data, data.tingMap[i][0]);
              console.log("累计胡:",pai)
              await mjAction.hu(game, element.userId,pai,this,(game,userId,type2,notify2,iszimo2)=>{
                isHued=true
                type=type2
                iszimo=iszimo2
                notify=notify2
              });
            }
          }
        }
     }
    }

    if(!isHued){
      await mjAction.hu(
        game,
        userId,
        pai,
        this,
        async (game, userId, forceEnd = false,type2,notify2,iszimo2) => {
          isHued=true
          type=type2
          iszimo=iszimo2
          notify=notify2
        },
      );
    }
     //通知前端，有人和牌了
     await this.gateway.broadcastInRoom({
      seats: game.gameSeats,
      roomId: game.roomId,
      userId: userId,
      message: { userId: userId, type: type,iszimo:iszimo, hupai: notify,zhongma:game.zhongma },
      type: resp.game_hupai,
      includSender: true,
    });
    isHued =true
    await  this.doGameOver(game, userId);

    return isHued;
  }
  async guo(game, userId) {
    return   await mjAction.guo(
      game,
      userId,
      this,
     async (game, nextSeat) => {
      await  this.moveToNextUser(game, nextSeat);
      },
      async  (game, isGang) => {
        await this.doUserMoPai(game, isGang);
      },
      async  (game, pai) => {
        await this.loopgang(game, pai);
      },
    );
  }

  async doGameOver(game, userId, forceEnd = false,isagain=false) {
    let roomId = game.roomId;
    if (roomId == null) {
      return false;
    }
    // const roomInfo: any = await this.redisService.hget('createroom_' + roomId);
    const roundInfo: any = {};

    let results = [];
    if (game != null &&game.gameSeats.length>0) {
      if(!isagain){
        this.calculateResult(game);
      }
      for (let i = 0; i < game.gameSeats.length; ++i) {

        let sd = game.gameSeats[i];

        if (!sd) continue;
        let userRT: any = {
          userId: sd.userId,
          holds: sd.holds,
          penggangs: sd.penggangs,
          fan: sd.fan,
          score: sd.score,
          pattern: sd.pattern,
          actions: [],
          numZiMo : sd.numZiMo,
          numJiePao : sd.numJiePao,
          numDianPao : sd.numDianPao,
          numAnGang: sd.numAnGang,
          numDianGangs: sd.numDianGangs,
          numMingGang : sd.numWanGangs,
          chi : sd.chi
        };
        if (sd.isHaiDiHu) userRT.haidihu = 1;
        if (sd.isTianHu) userRT.tianhu = 1;
        if (sd.isDiHu) userRT.dihu = 1;

        for (let k in sd.actions) {
          userRT.actions[k] = {
            type: sd.actions[k].type,
          };
        }
        results.push(userRT);
        
        sd = null; //清除数据
      }
      roundInfo.users = results;
      if (game.yipaoduoxiang >= 1) {
        roundInfo.nextButton = game.zhuanyi;
      } else if (game.firstHupai >= 0) {
        roundInfo.nextButton = game.firstHupai;
      } else {
        roundInfo.nextButton = (game.button + 1) % roundInfo.users.length;
      }
    }
   
    console.log(forceEnd, game);
    if (forceEnd || game == null) {
      this.fnNoticeResult(game,userId,true,roundInfo,isagain);
    } else {
      this.fnNoticeResult(game,userId,false,roundInfo,isagain);
    }
  }

  async  fnNoticeResult  (game,userId,isEnd,roundInfo,isagain)  {
    let endInfo = null;
    isEnd =  (game.numOfGames+1)  >= game.maxGames?true:isEnd;
    if(roundInfo!=null && !isagain){
      const res1: any = await this.roomService.addRound({userId,roomId:game.roomId,sceneId:game.sceneId,round:roundInfo,model:1});
        // 更新room 和 缓存
        await this.roomService.updateRoom(roundInfo.nextButton,game.roomId)
    }
    if (isEnd) {
      endInfo = [];
      
      endInfo = await this.roomService.getRound(game.sceneId);
      let data :any={ results: roundInfo.users}
      if(endInfo && endInfo.scores){
        data = { ...data, endInfo: JSON.parse(endInfo.scores)}
      }
      this.gateway.broadcastInRoom({
        seats: game.gameSeats,
        roomId: game.roomId,
        userId: userId,
        message: data,
        type: resp.game_over,
        includSender: true,})
    }else{
      this.gateway.broadcastInRoom({
        seats: game.gameSeats,
        roomId: game.roomId,
        userId: userId,
        message: { results: roundInfo.users},
        type: resp.game_over,
        includSender: true,
      });
    }

   
    
    //如果局数已够，则进行整体结算，并关闭房间
    game.state = "idle";
    //保存游戏  socket消息过快 缓存数据没更新到 导致有动作但是状态不对
    await this.redisService.hset({
      key: 'game' + game.roomId,
      value: { ...game },
      expire: defaultConfig.scoreCacheTime, // 3秒  为了就是瞬时刷新过快 导致的mysql问题
    });
    if (isEnd) {
     
      
    } else {
      console.log('一局结束了', game.numOfGames);
     
      game.gameSeats =null;
    }

  };

  calculateResult(game) {
    let baseScore = 1;
    let fan = 1;
    for (let i = 0; i < game.gameSeats.length; i++) {
      let sd = game.gameSeats[i];
      sd.numAnGang = 0;
      sd.numDianGangs = 0;
      sd.numWanGangs = 0;
      sd.score1 = 0;
      let dahu=false;
      for (let j = 0; j < sd.penggangs.length; j++) {
        if (sd.penggangs[j][0] == 'angang') {
          sd.numAnGang++;
        } else if (sd.penggangs[j][0] == 'diangang') {
          sd.numDianGangs++;
        } else if (sd.penggangs[j][0] == 'wangang') {
          sd.numWanGangs++;
        }
      }

      // 起手胡
      for (let j = 0; j < sd.actions.length; j++) {
        //循环遍历玩家动作
        let ac = sd.actions[j];
        if (
          ac.type == 'BanBanHu' ||
          ac.type == 'QueYiSe' ||
          ac.type == 'YiZhiHua' ||
          ac.type == 'DaSiXi' ||
          ac.type == '66Shun'
        ) {
          let additonalscore = fan * baseScore;
          //扣掉目标方的分
          let total1 = 0;
          let sdIndex = sd.seatIndex;

          if ( game.gameSeats.length == 2) {
            sdIndex=(sdIndex ==1)?2:sdIndex
          } else if (game.gameSeats.length  == 3) {
            sdIndex=(sdIndex ==2)?3:sdIndex
          }
          for (let index = 0; index < game.gameSeats.length; index++) {
            const element = game.gameSeats[index];
            let seatIndex = element.seatIndex;
            // 没有的索引 扣基础分 // 排除自己
            if ( game.gameSeats.length == 2) {
              seatIndex=(seatIndex ==1)?2:seatIndex
            } else if (game.gameSeats.length  == 3) {
              seatIndex=(seatIndex ==2)?3:seatIndex
            }
           
              if (ac.targets.includes(seatIndex)||ac.targets.includes(sdIndex)) {
                for (let t = 0; t < ac.targets.length; ++t) {
                  
                  if (seatIndex == ac.targets[t]||seatIndex ==sdIndex) {
                    total1 += additonalscore * 2;
                    element.score -= additonalscore * 2;
                    break;
                  }
                }
              } else {
                // 排除过了的
                if(ac.targets.length>0){
                  total1 += additonalscore;
                  element.score -= additonalscore;
                }
              }
           
          }
          sd.score1 += total1;
        } else if (
          ac.type == 'zimo' ||
          ac.type == 'hu' ||
          ac.type == 'qiangganghu' ||
          ac.type == 'hao7dui' ||
          ac.type == '7dui' ||
          ac.type == 'JiangHu' ||
          ac.type == 'PengHu' ||
          ac.type == 'QuanQiuRen' ||
          ac.type == 'QingYiSe' ||
          ac.type == 'ganghua' ||
          ac.type == 'dianganghua'
        ) {
          fan = 1;
          if (
            ac.type == 'hao7dui' ||
            ac.type == '7dui' ||
            ac.type == 'JiangHu' ||
            ac.type == 'PengHu' ||
            ac.type == 'QuanQiuRen' ||
            ac.type == 'QingYiSe' ||
            ac.type == 'ganghua' ||
            ac.type == 'dianganghua'
          ) {
            fan = fan * 4;

            //大胡累乘不累加
            if(dahu){
              sd.score = sd.score *2
              continue 
            }
            dahu=true
          }
          let additonalscore = fan * baseScore;
          let total = 0;
          //判断骰子中了没
           // round 是主人视角算出的 seatIndex
           let round=[]
          if ( game.gameSeats.length == 2) {
            round[0]=( game.round[0] ==1 ||  game.round[0] ==3)?-1:game.round[0]
            round[0] = game.round[0] == 2 ? 1 :  game.round[0];
          } else if (game.gameSeats.length  == 3) {
            round[0]=( game.round[0] ==2)?-1:game.round[0]

            round[0] = game.round[0] == 3 ? 2 : game.round[0];
          }
          if (game.gameSeats.length  == 2) {
            round[1]=( game.round[1] ==1 ||  game.round[1] ==3)?-1: game.round[1]
            round[1] =  game.round[1] == 2 ? 1 :  game.round[1];
          } else if (game.gameSeats.length  == 3) {
            round[1]=(  game.round[1] ==2)?-1: game.round[1]
            round[1] = game.round[1] == 3 ? 2 : game.round[1];
          }
          
          for (let t = 0; t < ac.targets.length; ++t) {
            if (
              round.includes(ac.targets[t]) ||
              round.includes(sd.seatIndex)
            ) {
             
              if (
                round[0] == ac.targets[t] ||
                round[0] == sd.seatIndex
              ) {
                total += additonalscore * 2;
                game.gameSeats[ac.targets[t]].score -= additonalscore * 2;
              }
              if (
                round[1] == ac.targets[t] ||
                round[1] == sd.seatIndex
              ) {
                total += additonalscore * 2;
                game.gameSeats[ac.targets[t]].score -= additonalscore * 2;
              }
            } else {
              total += additonalscore;
              game.gameSeats[ac.targets[t]].score -= additonalscore;
            }
          }

          console.log( ac.type,total,"round:",round,"seatIndex:",sd.seatIndex)
          sd.score = total;
          sd.fan = total;
        }
      }

      sd.score =sd.score+sd.score1
    }
  }
}
